home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
mpfeel.lha
/
MPFeel
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-07
|
30KB
|
1,334 lines
/* ******************************************************************** */
/* main.c Copyright (C) Codemist and University of Bath 1989 */
/* */
/* User top level */
/* ******************************************************************** */
/*
* $Id: main.c,v 1.15 1992/03/13 18:08:06 pab Exp $
*
* $Log: main.c,v $
* Revision 1.15 1992/03/13 18:08:06 pab
* SysV fixes (interpreter thread sort out)
*
* Revision 1.14 1992/02/18 11:16:06 pab
* added handler
*
* Revision 1.13 1992/02/11 13:38:32 pab
* fixed generic version
*
* Revision 1.12 1992/02/11 12:06:05 pab
* handler around load of initcode
*
* Revision 1.11 1992/02/10 12:07:02 pab
* Bytecode support
*
* Revision 1.10 1992/01/29 13:42:12 pab
* sysV fixes
*
* Revision 1.9 1992/01/17 22:31:19 pab
* fixed to load initcode at startup
*
* Revision 1.7 1992/01/09 22:28:53 pab
* Fixed for low tag ints
*
* Revision 1.6 1991/12/22 15:14:18 pab
* Xmas revision
*
* Revision 1.5 1991/11/15 13:45:08 pab
* copyalloc rev 0.01
*
* Revision 1.4 1991/10/08 19:27:42 pab
* arg to init_elvira changed
*
* Revision 1.3 1991/09/22 19:14:37 pab
* Fixed obvious bugs
*
* Revision 1.2 1991/09/11 12:07:24 pab
* 11/9/91 First Alpha release of modified system
*
* Revision 1.1 1991/08/12 16:49:47 pab
* Initial revision
*
* Revision 1.18 1991/04/03 21:06:36 kjp
* -cons-cut-off option
*
* Revision 1.17 1991/04/03 16:28:06 kjp
* History modifications - incomplete
*
* Revision 1.16 1991/04/02 16:41:32 kjp
* Conses command line option.
*
* Revision 1.15 1991/02/28 14:00:52 kjp
* Command line stack-space option.
*
* Revision 1.14 1991/02/13 18:23:09 kjp
* Pass.
*
*/
#define JMPDBG(x)
#define CODBG(x) /* fprintf(stderr,"CODBG:");x;fflush(stderr) */
/*
* Change Log:
* Version 1, April 1989
* Read a .feelrc file if it exists - JPff
* Various changes for streams
* Remove Env argument from make_module_function and make_special
* as always NULL
* Initialise threads.
* Added a one result history and fiddled with some object definitions.
*/
#include "version.h"
#include "defs.h"
#include "structs.h"
#include "funcalls.h"
#include "error.h"
#include "global.h"
#include "slots.h"
/*#include "compact.h" */
#include "garbage.h" /* What do I need this for */
#include "symboot.h"
#include "modules.h"
#include "toplevel.h"
#include "root.h"
#include "specials.h"
#include "lists.h"
#include "listops.h"
#include "calls.h"
#include "ccc.h"
#include "allocate.h"
#include "modboot.h"
#include "state.h"
#include "macros.h"
#include "semaphores.h"
#include "format.h"
#include "modops.h"
#include "sio.h"
#if (defined(WITH_BSD_SOCKETS) || defined(WITH_SYSTEMV_SOCKETS))
#include "sockets.h"
#endif
#ifdef WITH_BYTECODE /* Bytecode interpreter stack */
#include "bcstack.h"
#endif
/*
* Hack number 1A - push everything as yet unmodulised into OTHER
*/
#define OTHER_ENTRIES 24
MODULE Module_others;
LispObject Module_others_values[OTHER_ENTRIES];
/*
* The provided classes / constants / symbols
*/
/* Built in constants */
LispObject nil;
LispObject lisptrue;
LispObject unbound;
/* Root class */
LispObject Object;
/* Meta classes */
LispObject Standard_Class;
LispObject Slot_Description_Class;
LispObject Abstract_Class;
LispObject Slot_Description;
LispObject Local_Slot_Description;
LispObject Basic_Structure;
/* Allocation specifying metaclasses */
LispObject Structure_Class; /* Analogous to C structs */
LispObject Funcallable_Object_Class; /* Function forms */
LispObject Generic_Class;
LispObject Pair_Class;
LispObject Unpredictable_Fixed_Size_Class; /* Vector-type things */
LispObject Variable_Size_Keyed_Class; /* Tabular instances */
LispObject Thread_Class;
LispObject Method_Class;
/* Built in stuff */
LispObject Primitive_Class;
/* The core building blocks */
LispObject Abstract_Class; /* Meta */
LispObject Number, Complex, Real, Rational, Integer;
LispObject Symbol, Character, String;
LispObject Thread, Continue;
LispObject Function, Generic, Method, Macro;
/* Composites */
LispObject Cons, Vector, Table, Null; /* Empty list... */
/* Special pointer */
LispObject Weak_Wrapper;
/* Flag thing */
LispObject last_evaluated_expression; /* Input help */
LispObject top_level(LispObject*);
extern FILE* current_output;
/* Quick way of making self evaluating sybols */
void make_special_symbol(LispObject *stacktop, LispObject *objptr, char *name )
{
*objptr = (LispObject) get_symbol(stacktop, name );
lval_typeof(*objptr) = TYPE_SYMBOL;
gcof((*objptr)) = 0;
((*objptr)->SYMBOL).right = NULL;
}
/* Map maker... */
void make_map(LispObject *stacktop)
{
extern LispObject global_module_table;
extern LispObject Fn_table_parameters(LispObject*);
LispObject mods;
FILE *byfun;
FILE *bymod;
byfun = fopen("/opt/home/kjp/You/Maps/funmap.map","w");
bymod = fopen("/opt/home/kjp/You/Maps/modmap.map","w");
EUCALLSET_1(mods, Fn_table_parameters, global_module_table);
while (is_cons(mods)) {
LispObject mod;
LispObject exp;
mod = CAR(mods); mods = CDR(mods);
if (is_c_module(mod)) {
fprintf(bymod,"Compiled module '%s' exports:\n\n",
mod->C_MODULE.name->SYMBOL.pname);
}
else {
fprintf(bymod,"Interpreted module '%s' exports:\n\n",
mod->I_MODULE.name->SYMBOL.pname);
}
exp = mod->I_MODULE.exported_names;
while (is_cons(exp)) {
LispObject name;
name = CAR(exp); exp = CDR(exp);
fprintf(bymod,"\t\t\t\t\t%s\n ",name->SYMBOL.pname);
fprintf(byfun,"%-40s%s\n",
name->SYMBOL.pname,mod->I_MODULE.name->SYMBOL.pname);
}
fprintf(bymod,"\n");
}
fclose(bymod);
fclose(byfun);
}
/* Top level thread holder... */
LispObject interpreter_thread;
/* Temporary-ish jump buffer... */
LispObject tl_thread;
jmp_buf temp_buffer;
extern LispObject read_eval_print_continue;
LispObject boot_thread;
int main(int argc, char ** argv)
{
void load_and_boot(LispObject *);
extern void runtime_initialise_allocator(LispObject*);
void configure(int,char **);
void start_interpreter(LispObject*);
LispObject *gc_local_stack;
configure(argc,argv);
/*
* System initialisation...
*/
runtime_initialise_system(); /* Rig system spec stuff */
runtime_initialise_allocator(NULL);
runtime_initialise_garbage_collector(NULL);
#ifdef WITH_BYTECODE
/* Initialize bytecode interpreter stack */
init_stack();
#endif
OFF_collect();
/*
* We gotta rig up something so that we can use a few basic system
* functions during the main bootstrap sequence - this implies
* just setting up what will become the interpreter thread enough
* to get us moving...
*/
/*
* Set up preliminary thread stuff...
*/
/* Interpreter GC stack (nominal, for bootstrapping)... */
gc_local_stack = (LispObject*) malloc(4096*sizeof(LispObject*));
if (gc_local_stack == NULL) {
fprintf(stderr,"Really nasty error: unable to malloc gc_local_stack\n");
exit(1);
}
fprintf(stderr,"stack: 0x%x Lim: 0x%x\n",
gc_local_stack,
gc_local_stack + 4096);
/* Allocate the top level thread... */
nil = NULL;
Thread = NULL;
boot_thread
= allocate_thread(gc_local_stack,0,0,0);
/* Fill in as best we can... */
boot_thread->THREAD.stack_base = NULL;
boot_thread->THREAD.gc_stack_base = gc_local_stack;
boot_thread->THREAD.state->CONTINUE.gc_stack_pointer = gc_local_stack;
boot_thread->THREAD.stack_base = NULL;
boot_thread->THREAD.gc_stack_base = gc_local_stack;
boot_thread->THREAD.stack_size = 0xffffffff; /* lots'n'lots */
boot_thread->THREAD.gc_stack_size = 100*HUNK_PAGE_SIZE()*sizeof(LispObject*);
boot_thread->THREAD.fun = nil;
boot_thread->THREAD.args = nil;
boot_thread->THREAD.value = nil;
boot_thread->THREAD.status = NULL;
boot_thread->THREAD.parent = nil;
boot_thread->THREAD.cochain = nil;
/* Thread continuation... */
boot_thread->THREAD.state->CONTINUE.thread = boot_thread;
boot_thread->THREAD.state->CONTINUE.value = nil;
boot_thread->THREAD.state->CONTINUE.target = nil;
/* boot_thread->THREAD.state.machine_state; */
boot_thread->THREAD.state->CONTINUE.gc_stack_pointer = gc_local_stack;
boot_thread->THREAD.state->CONTINUE.dynamic_env = NULL;
boot_thread->THREAD.state->CONTINUE.last_continue = nil;
boot_thread->THREAD.state->CONTINUE.handler_stack = nil;
boot_thread->THREAD.state->CONTINUE.live = FALSE;
boot_thread->THREAD.state->CONTINUE.unwind = FALSE;
/*
* We have a 'serviceable' thread - initialise the system specific
* bits for serial initialisation...
*/
{
LispObject *stacktop;
stacktop = load_thread(boot_thread); /* Context to this thread... */
add_root(&boot_thread);
load_and_boot(stacktop); /* Do module boot sequence... */
interpreter_thread=EUCALL_2(Fn_cons,nil,nil);
read_eval_print_continue=EUCALL_2(Fn_cons,nil,nil);
tl_thread=EUCALL_2(Fn_cons,nil,nil);
add_root(&interpreter_thread);
add_root(&read_eval_print_continue);
add_root(&tl_thread);
start_interpreter(stacktop); /* Start the interpreter... */
}
}
#define INTERPRETER_THREAD_STACK_SIZE (64*1024*1)
#define INTERPRETER_THREAD_GC_STACK_SIZE (32*1024*1)
#ifndef MACHINE_ANY
void start_interpreter(LispObject *stacktop)
{
extern LispObject Fn_thread_start(LispObject*);
void start_history(void);
LispObject function_read_eval_print;
CAR(interpreter_thread)
= allocate_thread(stacktop, INTERPRETER_THREAD_STACK_SIZE,
INTERPRETER_THREAD_GC_STACK_SIZE,0);
function_read_eval_print =
allocate_module_function(stacktop, nil,nil,top_level,0);
CAR(interpreter_thread)->THREAD.fun = function_read_eval_print;
CAR(interpreter_thread)->THREAD.status = THREAD_LIMBO;
system_thread_rig(stacktop,CAR(interpreter_thread));
/* Install as ready... */
EUCALL_2(Fn_thread_start,CAR(interpreter_thread),nil);
CAR(read_eval_print_continue) = allocate_continue(stacktop);
#ifndef KJP
start_history();
#endif
/* Store as the top level thread... */
tl_thread = CAR(interpreter_thread);
/* Name and configuration... */
printf("EuLISP FEEL: Version (%d.%.02d ",MAJOR_VERSION,MINOR_VERSION);
#ifdef KJP
#ifdef MACHINE_SYSTEMV
printf("KJP-SystemV)");
#endif
#ifdef MACHINE_BSD
printf("KJP-BSD)");
#endif
#ifdef MACHINE_ANY
printf("KJP-Generic)");
#endif
#ifdef FIX_LEVEL
printf(" (fix %d)",FIX_LEVEL);
#endif
#else /* KJP */
#ifdef MACHINE_SYSTEMV
printf("SystemV)");
#endif
#ifdef MACHINE_BSD
printf("BSD)");
#endif
#ifdef MACHINE_ANY
printf("Generic)");
#endif
#ifdef FIX_LEVEL
printf(" (fix %d)",FIX_LEVEL);
#endif
#endif /* KJP */
printf(" %s\n",MAKE_DATE);
printf("\n");
#ifdef VERSION_MESSAGE
printf(" Version Message\n\n");
printf(VERSION_MESSAGE);
printf("\n");
#endif
fflush(stdout);
ON_collect();
{LispObject xx;
xx=boot_thread;
boot_thread=nil;
runtime_begin_processes(xx->THREAD.state->CONTINUE.gc_stack_pointer);
}
}
#else
void start_interpreter(LispObject *stacktop)
{
void start_history(void);
/* Generate the interpreter thread... */
CAR(interpreter_thread )
= allocate_thread(stacktop, 0,INTERPRETER_THREAD_GC_STACK_SIZE,0);
CAR(interpreter_thread)->THREAD.fun = nil;
CAR(interpreter_thread)->THREAD.status = THREAD_RUNNING;
CAR(read_eval_print_continue) = allocate_continue(stacktop);
#ifndef KJP
start_history();
#endif
/* Store as the top level thread... */
CAR(tl_thread) = CAR(interpreter_thread);
/* Name and configuration... */
ON_collect();
printf("EuLISP FEEL: Version (%d.%.02d ",MAJOR_VERSION,MINOR_VERSION);
#ifdef KJP
#ifdef MACHINE_SYSTEMV
printf("KJP-SystemV)");
#endif
#ifdef MACHINE_BSD
printf("KJP-BSD)");
#endif
#ifdef MACHINE_ANY
printf("KJP-Generic)");
#endif
#ifdef FIX_LEVEL
printf(" (fix %d)",FIX_LEVEL);
#endif
#else /* KJP */
#ifdef MACHINE_SYSTEMV
printf("SystemV)");
#endif
#ifdef MACHINE_BSD
printf("BSD)");
#endif
#ifdef MACHINE_ANY
printf("Generic)");
#endif
#ifdef FIX_LEVEL
printf(" (fix %d)",FIX_LEVEL);
#endif
#endif /* KJP */
printf(" %s\n",MAKE_DATE);
printf("\n");
#ifdef VERSION_MESSAGE
printf(" Version Message\n\n");
printf(VERSION_MESSAGE);
printf("\n");
#endif
fflush(stdout);
stacktop = load_thread(CAR(tl_thread)); /* So repl continue has the right thread base */
ON_collect();
(void) top_level(stacktop);
}
#endif
void load_and_boot(LispObject *stacktop)
{
extern MODULE Module_generics;
extern int gc_enabled;
extern void initialise_elvira_modules(LispObject *);
bootstrap(stacktop); /* Bootstrap classes and some special symbols */
initialise_modules(stacktop);
initialise_symbols(stacktop); /* Rig up the others */
initialise_specials(stacktop);
initialise_root(stacktop);
/* Hacked history */
make_special_symbol(stacktop, &last_evaluated_expression, ":last" );
/* Open up the other module and do the rest */
open_module(stacktop,
&Module_others,Module_others_values,"others",OTHER_ENTRIES);
initialise_set(stacktop);
initialise_basic(stacktop);
initialise_garbage(stacktop);
initialise_macros(stacktop);
close_module();
lval_typeof((LispObject)&Module_generics)=TYPE_C_MODULE;
/* Initialise the modular sections */
initialise_error(stacktop);
initialise_classes(stacktop);
initialise_streams(stacktop);
initialise_generics(stacktop);
initialise_ccc(stacktop);
initialise_lists(stacktop);
initialise_listops(stacktop);
initialise_tables(stacktop);
initialise_vectors(stacktop);
initialise_chars(stacktop);
initialise_calls(stacktop);
initialise_arith(stacktop);
initialise_threads(stacktop);
initialise_semaphores(stacktop);
/*
INIT_plural(stacktop);
*/
initialise_formatted_io(stacktop);
initialise_module_operators(stacktop);
INIT_plural(stacktop);
#if (defined(WITH_BSD_SOCKETS) || defined(WITH_SYSTEMV_SOCKETS))
{
extern void initialise_sockets(void);
initialise_sockets();
}
#endif
initialise_bit_vectors(stacktop);
#ifdef WITH_BIGNUMS
initialise_bignums(stacktop);
#endif
#ifdef BCI
initialise_bci(stacktop);
#endif
/* Set up Elvira modules... */
/* Note: because these may contain init-errors, we provide a handler */
{
extern LispObject function_bootstrap_handler;
LispObject xx;
EUCALLSET_2(xx,Fn_cons,function_bootstrap_handler,nil);
HANDLER_STACK() =
CURRENT_THREAD()->THREAD.state->CONTINUE.handler_stack
= xx;
}
initialise_elvira_modules(stacktop);
}
LispObject read_eval_print_continue;
/* This top-level is the function which is run on the interpreter thread... */
int command_line_do_done_flag;
int feelrc_read_flag;
LispObject top_level(LispObject *stacktop)
{
extern char *command_line_do_string;
extern int command_line_map_flag;
LispObject get_history_form(LispObject);
void put_history_form(LispObject *,LispObject);
int get_history_count(void);
void initialise_input_processing(void);
LispObject process_input_form(LispObject);
LispObject process_result_form(LispObject);
if (command_line_map_flag) make_map(stacktop);
CODBG(fprintf(stderr,"Entering toplevel on thread %d\n",THIS_PROCESS));
current_output = (StdOut->STREAM).handle;
SYSTEM_GLOBAL_VALUE(current_interactive_module) =
get_module(stacktop,sym_root);
command_line_do_done_flag = FALSE;
feelrc_read_flag = FALSE;
#ifdef KJP
initialise_input_processing();
#endif
/* Load the initialisation module */
{
LispObject sym_init;
extern LispObject function_bootstrap_handler;
extern LispObject function_default_handler;
LispObject xx,oldstack;
sym_init=get_symbol(stacktop,"initcode");
EUCALLSET_2(xx,Fn_cons,function_bootstrap_handler,nil);
HANDLER_STACK() = xx;
EUCALL_1(load_module,sym_init);
HANDLER_STACK()=CDR(xx);
EUCALLSET_2(xx,Fn_cons,function_default_handler,nil);
HANDLER_STACK() = xx;
}
reset:
if (set_continue(stacktop,CAR(read_eval_print_continue))) {
if (CAR(read_eval_print_continue)->CONTINUE.value == lisptrue) {
(void) garbage_collect(stacktop);
printf("\n");
fflush(stdout);
}
#ifdef KJP
/* Being here implies that no result was returned from the last
expression so we'll add a dummy value to the value history */
(void) process_result_form(nil);
#endif
/* Doc Frankenstein would be proud... */
goto reset;
}
/* If do was configured, fix it... */
if (command_line_do_string != NULL && command_line_do_done_flag == FALSE) {
LispObject command,ans;
command_line_do_done_flag = TRUE;
BUFFER_PTR() = 0;
strcpy(BUFFER_START(),command_line_do_string);
fprintf(StdOut->STREAM.handle,"Doing: '%s'\n",BUFFER_START());
command = read_object(stacktop);
fprintf(StdOut->STREAM.handle,"Exp: ");
EUCALL_2(Fn_print,command,StdOut);
EUCALLSET_2(ans,process_top_level_form,
SYSTEM_GLOBAL_VALUE(current_interactive_module),
command);
fprintf(StdOut->STREAM.handle,"Done: ");
EUCALL_2(Fn_print,ans,StdOut);
fprintf(StdOut->STREAM.handle,"\n");
}
/* Load the configuration file... */
if (!feelrc_read_flag) {
extern char *getenv(char *);
extern LispObject Fn_close(LispObject*);
char path[1000];
FILE *inits;
LispObject initstr;
char *home;
feelrc_read_flag = TRUE;
home = getenv("HOME");
if (home == NULL) path[0] = '\0';
strcpy(path,home);
strcat(path,"/.feelrc");
inits = fopen(path,"r");
if (inits != NULL) {
initstr = allocate_stream(stacktop, inits,'r');
while (TRUE) {
LispObject form;
STACK_TMP(initstr);
EUCALLSET_1(form, Fn_read, initstr);
UNSTACK_TMP(initstr);
if (form == q_eof) break;
STACK_TMP(initstr);
EUCALL_2(process_top_level_form,
SYSTEM_GLOBAL_VALUE(current_interactive_module),
form);
UNSTACK_TMP(initstr);
}
EUCALL_1(Fn_close, initstr);
}
}
while (TRUE) {
extern char current_prompt_string[];
extern LispObject Gf_generic_write(LispObject*);
extern LispObject sym_pling_root;
extern LispObject sym_pling_exit;
extern int system_scheduler_number;
LispObject form, ans;
FILE *current_output;
current_output = (StdOut->STREAM).handle;
sprintf(current_prompt_string,"eulisp:%x:%s!%d> ",system_scheduler_number,
SYSTEM_GLOBAL_VALUE(current_interactive_module)
->I_MODULE.name->SYMBOL.pname,
get_history_count());
#ifndef GNUREADLINE
fprintf(current_output,"%s",current_prompt_string);
fflush(current_output);
#endif
EUCALLSET_1(form, Fn_read, nil);
#ifdef KJP
if ((form = process_input_form(form)) == NULL) break;
ans
= process_top_level_form(SYSTEM_GLOBAL_VALUE(current_interactive_module),
form);
ans = process_result_form(ans);
#else
form = get_history_form(form); /* never allocs */
STACK_TMP(form);
put_history_form(stacktop, form);
UNSTACK_TMP(form);
if (form == q_eof || form == sym_pling_exit) break;
if (form == sym_pling_root) {
SYSTEM_GLOBAL_VALUE(current_interactive_module) =
get_module(stacktop,sym_root);
ans = nil;
}
else {
EUCALLSET_2(ans,process_top_level_form,
SYSTEM_GLOBAL_VALUE(current_interactive_module),
form);
last_evaluated_expression = ans;
}
#endif
current_output = (StdOut->STREAM).handle;
if (GC_STACK_POINTER() != GC_STACK_BASE())
fprintf(current_output,"GC Error: ptr=%d (recovered)\n",
GC_STACK_POINTER() - GC_STACK_BASE());
/** hack **/
GC_STACK_POINTER() = GC_STACK_BASE();
fprintf(current_output,"eulisp:%x:%s!%d< ",system_scheduler_number,
SYSTEM_GLOBAL_VALUE(current_interactive_module)
->I_MODULE.name->SYMBOL.pname,
get_history_count()-1);
EUCALL_2(Gf_generic_write,ans,StdOut);
fprintf(current_output,"\n\n");
fflush(current_output);
}
fprintf(stderr,"\nEuLISP finishing\n\n");
system_lisp_exit(1);
return nil;
}
/*
* Configuration...
*/
char *command_line_do_string;
int command_line_window_flag;
int command_line_heap_size;
int command_line_stack_space_size;
int command_line_map_flag;
int command_line_processors;
int command_line_interface_flag;
int command_line_cons_percentage;
int command_line_cons_cut_off;
void configure(int argc,char **argv)
{
extern int command_line_x_debug;
int i = 1;
/* Nullify options... */
command_line_do_string = NULL;
command_line_window_flag = FALSE;
command_line_heap_size = 0;
command_line_stack_space_size = 0;
command_line_map_flag = FALSE;
command_line_x_debug = FALSE;
command_line_interface_flag = FALSE;
command_line_processors = 0;
command_line_cons_percentage = 0;
command_line_cons_cut_off = 0;
while (i < argc) {
if (strcmp(argv[i],"-do") == 0) {
if (argc - i < 2) {
fprintf(stderr,"eulisp: bad -do option\n");
exit(1);
}
command_line_do_string = argv[i+1];
i+=2;
continue;
}
if (strcmp(argv[i],"-win") == 0) {
command_line_window_flag = TRUE;
++i;
continue;
}
if (strcmp(argv[i],"-xdebug") == 0
|| strcmp(argv[i],"-Xdebug") == 0) {
command_line_x_debug = TRUE;
++i;
continue;
}
if (strcmp(argv[i],"-heap") == 0) {
if (argc - i < 2) {
fprintf(stderr,"eulisp: bad -heap option\n");
exit(1);
}
sscanf(argv[i+1],"%d",&command_line_heap_size);
i+=2;
continue;
}
if (strcmp(argv[i],"-stack-space") == 0) {
if (argc - i < 2) {
fprintf(stderr,"eulisp: bad -stack-space option\n");
exit(1);
}
sscanf(argv[i+1],"%d",&command_line_stack_space_size);
i+=2;
continue;
}
if (strcmp(argv[i],"-conses") == 0) {
if (argc - i < 2) {
fprintf(stderr,"eulisp: bad -conses option\n");
exit(1);
}
sscanf(argv[i+1],"%d",&command_line_cons_percentage);
i+=2;
continue;
}
if (strcmp(argv[i],"-cons-cut-off") == 0) {
if (argc - i < 2) {
fprintf(stderr,"eulisp: bad -cons-cut-off option\n");
exit(1);
}
sscanf(argv[i+1],"%d",&command_line_cons_cut_off);
i+=2;
continue;
}
if (strcmp(argv[i],"-procs") == 0) {
if (argc - i < 2) {
fprintf(stderr,"eulisp: bad -procs option\n");
exit(1);
}
sscanf(argv[i+1],"%d",&command_line_processors);
if (command_line_processors < 1) {
fprintf(stderr,"eulisp: bad -procs value\n");
exit(1);
}
if (command_line_processors > MAX_PROCESSORS) {
fprintf(stderr,"eulisp: -procs value higher than %d maximum\n",
MAX_PROCESSORS);
exit(1);
}
i+=2;
continue;
}
if (strcmp(argv[i],"-map") == 0) {
command_line_map_flag = TRUE;
++i;
continue;
}
if (strcmp(argv[i],"-gen-interfaces") == 0) {
command_line_interface_flag = TRUE;
++i;
continue;
}
fprintf(stderr,"eulisp: unknown option '%s'\n",argv[i]);
exit(1);
}
/* From environment */
}
#ifdef KJP
/*
** Hacked histories...
**
** One to redo commands and one for values.
*/
typedef struct history_structure {
LispObject value_list;
int count;
} History;
/* Abstract operations */
static void initialise_history(History *h)
{
h->value_list = nil;
h->count = 0;
}
static void add_history_value(History *h,LispObject value)
{
extern LispObject Fn_nconc(LispObject*);
++(h->count);
EUCALLSET_2(value, Fn_cons, value, nil);
EUCALLSET_2(h->value_list, Fn_nconc, h->value_list,value);
}
static LispObject get_history_value(History *h,int n)
{
LispObject walker;
int i;
if (n > h->count) return(NULL);
for (walker = h->value_list, i = 0; i < n; ++i, walker = CDR(walker));
return(CAR(walker));
}
static void show_history(History *h)
{
int i;
LispObject walker;
EUDECL(Gf_generic_write);
for (i = 0, walker = h->value_list;
is_cons(walker);
++i, walker = CDR(walker)) {
printf("%d: ",i);
(void) EUCALL_2(Gf_generic_write,CAR(walker),StdOut);
printf("\n");
fflush(stdout);
}
}
/* Our histories... */
/* Input history */
static SYSTEM_GLOBAL(History *,input_history);
/* Value history */
static SYSTEM_GLOBAL(History *,value_history);
static int history_index(History *h,LispObject sym,char *prefix)
{
int len,index,i;
len = strlen(prefix);
/* Too short or not right? */
if (strlen(sym->SYMBOL.pname) < len) return(-1);
if (strncmp(sym->SYMBOL.pname,prefix,len) != 0) return(-1);
/* Exactly right? */
if (strlen(sym->SYMBOL.pname) == len) return(h->count-1);
/* All digits */
for (i = len; sym->SYMBOL.pname[i] != '\0'; ++i)
if (!isdigit(sym->SYMBOL.pname[i])) return(-1);
/* Get the number */
sscanf(&(sym->SYMBOL.pname[len]),"%d",&index);
/* OK? */
if (index >= h->count || index < 0) return(-1);
return(index);
}
void add_input_history_value(LispObject form)
{
add_history_value(SYSTEM_GLOBAL_VALUE(input_history),form);
}
LispObject input_history_replace(LispObject sym)
{
int index;
index = history_index(SYSTEM_GLOBAL_VALUE(input_history),sym,"!");
if (index < 0) return(sym);
return(get_history_value(SYSTEM_GLOBAL_VALUE(input_history),index));
}
void add_value_history_value(LispObject form)
{
add_history_value(SYSTEM_GLOBAL_VALUE(value_history),form);
}
LispObject value_history_replace(LispObject sym)
{
int index;
index = history_index(SYSTEM_GLOBAL_VALUE(value_history),sym,"!!");
if (index < 0) return(sym);
return(get_history_value(SYSTEM_GLOBAL_VALUE(value_history),index));
}
LispObject replace_with_history_value(LispObject sym)
{
return(value_history_replace(input_history_replace(sym)));
}
static void initialise_histories()
{
SYSTEM_INITIALISE_GLOBAL(History *,input_history,
(History *) system_static_malloc(sizeof(History)));
SYSTEM_INITIALISE_GLOBAL(History *,value_history,
(History *) system_static_malloc(sizeof(History)));
initialise_history(SYSTEM_GLOBAL_VALUE(input_history));
initialise_history(SYSTEM_GLOBAL_VALUE(value_history));
}
int get_history_count()
{
return(SYSTEM_GLOBAL_VALUE(input_history)->count);
}
#else /* KJP */
/* Old hacked histories */
static SYSTEM_GLOBAL(LispObject,history_list);
static SYSTEM_GLOBAL(int,history_list_length);
static SYSTEM_GLOBAL(int,history_count);
int get_history_count()
{
return(SYSTEM_GLOBAL_VALUE(history_count));
}
LispObject get_history_form(LispObject obj)
{
LispObject walker;
int i,n,pos;
if (!is_symbol(obj)) return(obj);
if (obj->SYMBOL.pname[0] != '!') return(obj);
i = 1;
while(obj->SYMBOL.pname[i] != '\0') {
if (!isdigit(obj->SYMBOL.pname[i])) return(obj);
++i;
}
sscanf(&(obj->SYMBOL.pname[1]),"%d",&n);
if (n > SYSTEM_GLOBAL_VALUE(history_count)) return(nil);
pos = SYSTEM_GLOBAL_VALUE(history_list_length) - n - 1;
for (walker = SYSTEM_GLOBAL_VALUE(history_list),i = 0;
i < pos;
++i, walker = CDR(walker));
return(CAR(walker));
}
void put_history_form(LispObject *stacktop, LispObject form)
{
++SYSTEM_GLOBAL_VALUE(history_count);
++SYSTEM_GLOBAL_VALUE(history_list_length);
EUCALLSET_2(SYSTEM_GLOBAL_VALUE(history_list), Fn_cons,
form,SYSTEM_GLOBAL_VALUE(history_list));
}
void start_history()
{
SYSTEM_INITIALISE_GLOBAL(LispObject,history_list,nil);
SYSTEM_INITIALISE_GLOBAL(int,history_list_length,0);
SYSTEM_INITIALISE_GLOBAL(int,history_count,0);
ADD_SYSTEM_GLOBAL_ROOT(history_list);
}
#endif /* KJP */
#ifdef KJP
/*
** Noddy input processing
*/
static LispObject sym_pling_root;
static LispObject sym_pling_exit;
static LispObject sym_pling_b;
static LispObject sym_pling_backtrace;
static LispObject sym_pling_q;
static LispObject sym_pling_quickie;
static LispObject sym_pling_c;
static LispObject sym_pling_commands;
static LispObject sym_pling_v;
static LispObject sym_pling_values;
LispObject process_input_form(LispObject form)
{
add_input_history_value(form);
/* We only know about magic symbols */
if (!is_symbol(form)) return(form);
/* Special symbols... */
/* !root */
if (form == sym_pling_root) {
SYSTEM_GLOBAL_VALUE(current_interactive_module) =
get_module(stacktop,sym_root);
return(nil);
}
/* EOF or !exit */
if (form == q_eof || form == sym_pling_exit) return(NULL);
/* !b or !backtrace */
if (form == sym_pling_b || form == sym_pling_backtrace) {
module_eval_backtrace();
return(nil);
}
/* !q or !quickie */
if (form == sym_pling_q || form == sym_pling_quickie) {
quickie_module_eval_backtrace();
return(nil);
}
/* !c or !commands */
if (form == sym_pling_c || form == sym_pling_commands) {
show_history(SYSTEM_GLOBAL_VALUE(input_history));
return(nil);
}
/* !v or !values */
if (form == sym_pling_v || form == sym_pling_values) {
show_history(SYSTEM_GLOBAL_VALUE(value_history));
return(nil);
}
/* We know nothing! */
return(form);
}
LispObject process_result_form(LispObject form)
{
add_value_history_value(form);
return(form);
}
void initialise_input_processing()
{
initialise_histories();
sym_pling_root = get_symbol(stacktop,"!root");
sym_pling_exit = get_symbol(stacktop,"!exit");
sym_pling_b = get_symbol(stacktop,"!b");
sym_pling_backtrace = get_symbol(stacktop,"!backtrace");
sym_pling_q = get_symbol(stacktop,"!q");
sym_pling_quickie = get_symbol(stacktop,"!quickie");
sym_pling_c = get_symbol(stacktop,"!c");
sym_pling_commands = get_symbol(stacktop,"!commands");
sym_pling_v = get_symbol(stacktop,"!v");
sym_pling_values = get_symbol(stacktop,"!values");
}
#endif /* KJP */